1 package edu.jiangxin.apktoolbox.convert.time;
2
3 import edu.jiangxin.apktoolbox.swing.extend.EasyPanel;
4 import edu.jiangxin.apktoolbox.utils.Constants;
5 import edu.jiangxin.apktoolbox.utils.DateUtils;
6
7 import javax.swing.*;
8 import javax.swing.text.DateFormatter;
9 import java.awt.*;
10 import java.awt.event.ActionEvent;
11 import java.awt.event.ActionListener;
12 import java.io.Serial;
13 import java.text.SimpleDateFormat;
14 import java.util.Arrays;
15 import java.util.Calendar;
16 import java.util.Date;
17 import java.util.TimeZone;
18
19 public class TimeConvertPanel extends EasyPanel {
20 @Serial
21 private static final long serialVersionUID = 1L;
22
23 private JSpinner timestamp2Spinner;
24
25 private JComboBox<Object> timestampComboBox;
26
27 private JTextField timeTextField;
28
29 private JTextField currentTimestampTextField;
30
31 private JTextField currentTimeTextField;
32
33 private JButton pauseButton;
34
35 private boolean isPaused;
36
37 private JFormattedTextField inTimeTextField;
38 private JComboBox<String> inTimezoneComboBox;
39 private JComboBox<String> outTimezoneComboBox;
40 private JTextField outTimeTextField;
41
42 private static final String SDF_PATTERN = "yyyy-MM-dd HH:mm";
43 private final SimpleDateFormat SDF = new SimpleDateFormat(SDF_PATTERN);
44 private final DateFormatter dtFormatter = new DateFormatter(SDF);
45
46 final static String[] sortedTimeZones;
47
48 static {
49 String[] t = TimeZone.getAvailableIDs();
50 sortedTimeZones = Arrays.copyOf(t, t.length);
51 Arrays.sort(sortedTimeZones, String.CASE_INSENSITIVE_ORDER);
52 }
53
54 public TimeConvertPanel() throws HeadlessException {
55 super();
56 }
57
58 @Override
59 public void initUI() {
60 BoxLayout boxLayout = new BoxLayout(this, BoxLayout.Y_AXIS);
61 setLayout(boxLayout);
62
63 createConvertPanel();
64 add(Box.createVerticalStrut(Constants.DEFAULT_Y_BORDER));
65
66 createConvertButtonsPanel();
67 add(Box.createVerticalStrut(Constants.DEFAULT_Y_BORDER * 3));
68
69 createCurrentPanel();
70 add(Box.createVerticalStrut(Constants.DEFAULT_Y_BORDER * 3));
71
72 createCommentPanel();
73 add(Box.createVerticalStrut(Constants.DEFAULT_Y_BORDER * 3));
74
75 createTimezonePanel();
76 }
77
78 private void createConvertPanel() {
79 JPanel convertPanel = new JPanel();
80 convertPanel.setLayout(new BoxLayout(convertPanel, BoxLayout.X_AXIS));
81 add(convertPanel);
82
83 JPanel timestampPanel = new JPanel();
84 timestampPanel.setLayout(new BoxLayout(timestampPanel, BoxLayout.X_AXIS));
85
86 JPanel timePanel = new JPanel();
87 timePanel.setLayout(new BoxLayout(timePanel, BoxLayout.X_AXIS));
88
89 convertPanel.add(timestampPanel);
90 convertPanel.add(Box.createHorizontalStrut(40));
91 convertPanel.add(timePanel);
92
93 JLabel timestampLabel = new JLabel("TimeStamp: ");
94
95 timestamp2Spinner = new JSpinner();
96 timestamp2Spinner.setPreferredSize(new Dimension(150, 25));
97 timestamp2Spinner.setModel(new SpinnerNumberModel(Long.valueOf(0L), Long.valueOf(0L), Long.valueOf(Long.MAX_VALUE), Long.valueOf(1L)));
98
99 timestampComboBox = new JComboBox<>();
100 timestampComboBox.addItem("Second(s)");
101 timestampComboBox.addItem("Millisecond(ms)");
102
103 timestampPanel.add(timestampLabel);
104 timestampPanel.add(Box.createHorizontalStrut(Constants.DEFAULT_X_BORDER));
105 timestampPanel.add(timestamp2Spinner);
106 timestampPanel.add(Box.createHorizontalStrut(Constants.DEFAULT_X_BORDER));
107 timestampPanel.add(timestampComboBox);
108
109 JLabel timeLabel = new JLabel("Time: ");
110
111 timeTextField = new JTextField(20);
112
113 timePanel.add(timeLabel);
114 timePanel.add(Box.createHorizontalStrut(Constants.DEFAULT_X_BORDER));
115 timePanel.add(timeTextField);
116 }
117
118 private void createConvertButtonsPanel() {
119 JPanel convertButtonsPanel = new JPanel();
120 BoxLayout boxLayout = new BoxLayout(convertButtonsPanel, BoxLayout.X_AXIS);
121 convertButtonsPanel.setLayout(boxLayout);
122 add(convertButtonsPanel);
123
124 JButton timestamp2TimeButton = new JButton();
125 timestamp2TimeButton.setText("Timestamp->Time");
126 timestamp2TimeButton.addActionListener(new Timestamp2TimeButtonActionListener());
127 convertButtonsPanel.add(timestamp2TimeButton);
128
129 convertButtonsPanel.add(Box.createHorizontalStrut(Constants.DEFAULT_X_BORDER));
130
131 JButton time2TimestampButton = new JButton();
132 time2TimestampButton.setText("Time->Timestamp");
133 time2TimestampButton.addActionListener(new Time2TimestampButtonActionListener());
134 convertButtonsPanel.add(time2TimestampButton);
135
136 convertButtonsPanel.add(Box.createHorizontalGlue());
137 }
138
139 private void createCurrentPanel() {
140 JPanel currentPanel = new JPanel();
141 BoxLayout boxLayout = new BoxLayout(currentPanel, BoxLayout.X_AXIS);
142 currentPanel.setLayout(boxLayout);
143 add(currentPanel);
144
145 JLabel currentTimestampLabel = new JLabel("Current timestamp: ");
146 currentPanel.add(currentTimestampLabel);
147 currentPanel.add(Box.createHorizontalStrut(Constants.DEFAULT_X_BORDER));
148
149 currentTimestampTextField = new JTextField();
150 currentPanel.add(currentTimestampTextField);
151 currentPanel.add(Box.createHorizontalStrut(Constants.DEFAULT_X_BORDER));
152
153 JLabel currentTimeTitleLabel = new JLabel("Current time: ");
154 currentPanel.add(currentTimeTitleLabel);
155 currentPanel.add(Box.createHorizontalStrut(Constants.DEFAULT_X_BORDER));
156
157 currentTimeTextField = new JTextField();
158 currentPanel.add(currentTimeTextField);
159 currentPanel.add(Box.createHorizontalStrut(Constants.DEFAULT_X_BORDER));
160
161 pauseButton = new JButton("Pause");
162 currentPanel.add(pauseButton);
163 pauseButton.addActionListener(e -> {
164 if (isPaused) {
165 pauseButton.setText("Pause");
166 isPaused = false;
167 } else {
168 pauseButton.setText("Resume");
169 isPaused = true;
170 }
171 });
172
173 new Thread(() -> {
174 while (true) {
175 long currentTimeStamp = System.currentTimeMillis() / 1000;
176 if (!isPaused) {
177 currentTimestampTextField.setText(String.valueOf(currentTimeStamp));
178 currentTimeTextField.setText(DateUtils.secondToHumanFormat(currentTimeStamp));
179 }
180 try {
181 Thread.sleep(1000);
182 } catch (InterruptedException e) {
183 logger.error("sleep InterruptedException");
184 Thread.currentThread().interrupt();
185 }
186 }
187 }).start();
188 }
189
190 private void createCommentPanel() {
191 JPanel commentPanel = new JPanel();
192 BoxLayout boxLayout = new BoxLayout(commentPanel, BoxLayout.X_AXIS);
193 commentPanel.setLayout(boxLayout);
194 add(commentPanel);
195
196 JTextArea textArea1 = new JTextArea("1s = 1000ms");
197 textArea1.setEditable(false);
198 JTextArea textArea2 = new JTextArea("1ms = 1000μs");
199 textArea2.setEditable(false);
200 JTextArea textArea3 = new JTextArea("1μs = 1000ns");
201 textArea3.setEditable(false);
202 JTextArea textArea4 = new JTextArea("1ns = 1000ps");
203 textArea4.setEditable(false);
204
205 commentPanel.add(textArea1);
206 commentPanel.add(Box.createHorizontalStrut(Constants.DEFAULT_X_BORDER));
207
208 commentPanel.add(textArea2);
209 commentPanel.add(Box.createHorizontalStrut(Constants.DEFAULT_X_BORDER));
210
211 commentPanel.add(textArea3);
212 commentPanel.add(Box.createHorizontalStrut(Constants.DEFAULT_X_BORDER));
213
214 commentPanel.add(textArea4);
215 commentPanel.add(Box.createHorizontalStrut(Constants.DEFAULT_X_BORDER));
216 }
217
218 private void createTimezonePanel() {
219 JPanel timezonePanel = new JPanel();
220 BoxLayout boxLayout = new BoxLayout(timezonePanel, BoxLayout.X_AXIS);
221 timezonePanel.setLayout(boxLayout);
222 add(timezonePanel);
223
224 JLabel label1 = new JLabel("From Time: ");
225 label1.setLabelFor(inTimeTextField);
226 timezonePanel.add(label1);
227
228 inTimeTextField = new JFormattedTextField(dtFormatter);
229 inTimeTextField.setToolTipText("Enter time (" + SDF_PATTERN + "): ");
230 inTimeTextField.setValue(new Date());
231 inTimeTextField.addPropertyChangeListener("value", event -> update());
232
233 JLabel label2 = new JLabel("From Timezone: ");
234 label2.setLabelFor(inTimezoneComboBox);
235 inTimezoneComboBox = new JComboBox<>(sortedTimeZones);
236 inTimezoneComboBox.setPreferredSize(new Dimension(70, 0));
237 inTimezoneComboBox.addActionListener(e -> update());
238
239 JLabel label3 = new JLabel("To Timezone: ");
240 label3.setLabelFor(outTimezoneComboBox);
241 outTimezoneComboBox = new JComboBox<>(sortedTimeZones);
242 outTimezoneComboBox.setPreferredSize(new Dimension(70, 0));
243 outTimezoneComboBox.addActionListener(e -> update());
244
245 JLabel label4 = new JLabel("To Time: ");
246 label4.setLabelFor(outTimeTextField);
247 outTimeTextField = new JTextField(10);
248
249 JButton swapButton = new JButton("Swap");
250 swapButton.addActionListener(e -> {
251 final String src = (String) inTimezoneComboBox.getSelectedItem();
252 inTimezoneComboBox.setSelectedItem(outTimezoneComboBox.getSelectedItem());
253 outTimezoneComboBox.setSelectedItem(src);
254 });
255
256 timezonePanel.add(label1);
257 timezonePanel.add(inTimeTextField);
258 timezonePanel.add(Box.createHorizontalStrut(Constants.DEFAULT_X_BORDER));
259 timezonePanel.add(label2);
260 timezonePanel.add(inTimezoneComboBox);
261 timezonePanel.add(Box.createHorizontalStrut(Constants.DEFAULT_X_BORDER));
262 timezonePanel.add(label3);
263 timezonePanel.add(outTimezoneComboBox);
264 timezonePanel.add(Box.createHorizontalStrut(Constants.DEFAULT_X_BORDER));
265 timezonePanel.add(label4);
266 timezonePanel.add(outTimeTextField);
267 timezonePanel.add(Box.createHorizontalStrut(Constants.DEFAULT_X_BORDER));
268 timezonePanel.add(swapButton);
269 }
270
271 private final class Timestamp2TimeButtonActionListener implements ActionListener {
272 @Override
273 public void actionPerformed(ActionEvent e) {
274 Long timestamp = (Long) timestamp2Spinner.getValue();
275 Integer index = timestampComboBox.getSelectedIndex();
276 String result = "";
277 if (index.equals(0)) {
278 result = DateUtils.secondToHumanFormat(timestamp);
279 } else if (index.equals(1)) {
280 result = DateUtils.millisecondToHumanFormat(timestamp);
281 }
282 timeTextField.setText(result);
283 }
284 }
285
286 private final class Time2TimestampButtonActionListener implements ActionListener {
287 @Override
288 public void actionPerformed(ActionEvent e) {
289 String string = timeTextField.getText();
290 Integer index = timestampComboBox.getSelectedIndex();
291 Long result = 0L;
292 if (index.equals(0)) {
293 result = DateUtils.humanFormatToSecond(string);
294 } else if (index.equals(1)) {
295 result = DateUtils.humanFormatToMillisecond(string);
296 }
297 timestamp2Spinner.setValue(result);
298 }
299 }
300
301
302 private void update() {
303
304 final TimeZone sourceTimezone = TimeZone.getTimeZone(
305 (String) inTimezoneComboBox.getSelectedItem());
306 final TimeZone destTimezone = TimeZone.getTimeZone(
307 (String) outTimezoneComboBox.getSelectedItem());
308
309
310 Date sourceDate = (Date) inTimeTextField.getValue();
311
312
313 Calendar localTime = Calendar.getInstance();
314 localTime.setTime(sourceDate);
315 Calendar sourceTime = Calendar.getInstance(sourceTimezone);
316 sourceTime.set(localTime.get(Calendar.YEAR),
317 localTime.get(Calendar.MONTH),
318 localTime.get(Calendar.DATE),
319 localTime.get(Calendar.HOUR_OF_DAY),
320 localTime.get(Calendar.MINUTE));
321
322
323 SimpleDateFormat sdf = (SimpleDateFormat) SDF.clone();
324 sdf.setTimeZone(destTimezone);
325 outTimeTextField.setText(sdf.format(sourceTime.getTime()));
326 }
327 }